<template>
  <div
    v-show="mappingProps.visible"
    class="tr-slider"
    :class="{
      'z-mobile': isMobile,
      'z-vertical':
        labelPosition == 'top' && !mappingProps.hideLabel && !isMobile,
    }"
    tabindex="-1"
  >
    <LabelPrefixWraper
      :labelProps="{ class: 'label-title' }"
      :label="mappingProps.label"
      :hideLabel="mappingProps.hideLabel"
      :labelPosition="labelPosition"
      :helpConf="mappingProps.helpConf"
      :helpTooltip="mappingProps.helpTooltip"
      :helpPlacement="mappingProps.helpPlacement"
      :helpMore="mappingProps.helpMore"
      :helpMorePopup="mappingProps.helpMorePopup"
      :helpMoreLink="mappingProps.helpMoreLink"
      :helpMoreLinkHrefStatic="mappingProps.helpMoreLinkHrefStatic"
      :helpMoreLinkHrefExp="mappingProps.helpMoreLinkHrefExp"
      :required="mappingProps.required"
      tabindex="-1"
    >
    </LabelPrefixWraper>

    <div class="tr-slider-value">
      <div class="tr-slider-cnt">
        <Slider
          class="tr-slider-cpt"
          :class="tSilderCptClass"
          v-show="mappingProps.visible"
          v-bind="{ ...attrs, ...mappingProps }"
          inner-track-color="inner_track_color"
          track-color="track_color"
          track-size="3px"
          :thumb-size="isMobile ? '20px' : '15px'"
          :color="color"
          :data-uid="undefined"
          :data-tag="undefined"
          :switchLabelSide="switchLabelSide"
          :switchMarkerLabelsSide="switchMarkerLabelsSide"
          :label="mappingProps.showLabel"
          @pan="onPanHandler"
          :markers="markers"
          :markerLabels="markerLabels"
          :labelAlways="labelAlways"
          :tabindex="mappingProps.tabIndex"
          v-model="mappingProps.modelValue"
          snap
        >
        </Slider>
      </div>

      <!-- 必填校验显示 -->
      <div v-if="displayedRequiredError" class="u-error-message">
        {{ mappingProps.requiredMessage }}
      </div>
    </div>
  </div>
</template>

<!-- ts只是方便开发提示和补全代码，没有用语法 -->

<script setup type="typescript">
import { computed, ref, useAttrs, useSlots, watchEffect, watch } from 'vue';
// 钩子方法
import { useFormChild, useQuasar } from '@teld/q-components';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
	commonProps
} from 't/common/utils';
// 组件
import Slider from '@teld/q-components/Slider';
import LabelPrefixWraper from '../label-prefix-wraper';



const $q = useQuasar();
// 浏览宽度低于768px
const isMobile = computed(() => $q.screen.xs || $q.platform.is.mobile);
// 直接映射透传qursor的属性
const attrs = useAttrs();
// 父级组件传递来的slots
const slots = useSlots();
// 组件传参
const props = defineProps(
	// 大小写不敏感
	{
		...commonProps,
		...Slider.props,
		...LabelPrefixWraper.props,
		// 是否显示标签
		showLabel: {
			type: Boolean,
			default: false,
		},
		// 是否显示标签
		label: {
			type: String,
			default: () => '',
		},
		// 弹出小标签位置 默认顶部
		popLabelPosition: {
			type: String,
			default() {
				return 'top';
			},
		},
		// 轨道标记数量
		markerStep: {
			type: Number,
			default() {
				return 10;
			},
		},
		// 轨道标记文字位置 默认底部
		markerPosition: {
			type: String,
			default() {
				return 'bottom';
			},
		},
		// 默认可见
		visible: {
			type: Boolean,
			default() {
				return true;
			},
		},
		// 必填校验相关
		required: {
			type: Boolean,
			default() {
				return false;
			},
		},
		requiredMessage: {
			type: String,
			default() {
				return '';
			},
		},
		tabIndex: {
			type: String,
			default() {
				return '0';
			},
		},
		// 选中颜色
		color: {
			type: String,
			// default: () =>
			// 	window
			// 		?.getComputedStyle(document.documentElement, ':root')
			// 		?.getPropertyValue('--t-color')
			// 		?.trim() || 'rgb(0, 120, 212)',
		},
	}
);

// 是否设计时
const inDesign = !!window['fas']?.inDesign;

// 大写首字母属性
const [mappingProps, mappingExpose] = useMappingProps(props);

// ============================= label 位置  ===========================
const labelPosition = computed(() => {
	if (isMobile.value) {
		return 'top';
	}
	return mappingProps.labelPosition;
});

const color = computed(() => {
	const { color } = mappingProps;
	if (!color || color === 'default') return 'teld_primary';
	return color;
});

// ============================= 轨道标记文字和标签位置 ===========================
const markers = computed(() => !mappingProps.markers ? mappingProps.markers : (mappingProps.markerStep || mappingProps.markers));
// 配置标记的标签（如果为'true'则显示默认值）；定义对象数组或键值对对象，其中键是模型，值是标记标签的定义。
const markerLabels = computed(() => {
	if (!markers.value) return false;
	const { markerLabels } = mappingProps;
	if (inDesign) {
		if (markerLabels === true || markerLabels === 'false') return false;
		if (markerLabels === 'true') return true;
	}
	// if (typeof markerLabels === 'string') return markerLabels === 'true';
	return markerLabels
});
const switchLabelSide = computed(() => mappingProps.popLabelPosition == 'bottom');
const switchMarkerLabelsSide = computed(() => mappingProps.markerPosition == 'top');
// 给q-slider组件附加的样式，为了让滑块和标题对齐
const tSilderCptClass = computed(() => {
	const { markerPosition, markers } = mappingProps;
	return {
		'z-markerLabels': labelPosition.value != 'top' && markerLabels.value,
		'z-markersAndMarkerLabels': labelPosition.value != 'top' && markers && markerLabels.value,
		'z-markerLabelsAndSwitch': labelPosition.value != 'top' && markerLabels.value && markerPosition == 'top',
		'z-markersAndMarkerLabelsAndSwitch': labelPosition.value != 'top' && markers && markerLabels.value && markerPosition == 'top',
	}
});
// 标签值映射
const labelAlways = computed(() => {
	const { showLabel, labelAlways } = mappingProps;
	return showLabel ? labelAlways : undefined
});

// ============================= 必填校验相关 ===========================
// 是否显示必填校验错误
const displayedRequiredError = ref(false);
// 必填校验，不能选0
function validate() {
	const { required, modelValue, requiredMessage } = mappingProps;
	const value = modelValue;
	displayedRequiredError.value = required && (typeof value === 'undefined' || value === null || value === 0 || value === '' || isNaN(value))
	return !displayedRequiredError.value
}
// 应该返回一个布尔值（或一个 resolve 布尔值的 Promise）
function resetValidation() {
	displayedRequiredError.value = false;
}

// ============================= 暴漏外部方法 ===========================
defineExpose({ ...mappingExpose, resetValidation, validate });

// 与qForm组件通信，校验用户输入是否合法
useFormChild({
	validate, // 函数；可以是异步的；
	resetValidation, // 可选的函数，可重置验证
	requiresQForm: false // 如果没有找到父级 QForm，它是否应该报错？
});

// ============================= 回调事件 ===========================
// 触发的emit事件
const emit = defineEmits(['pan', 'change', 'update:modelValue']);

// 点击事件
function onPanHandler(params) {
	emit('pan', params)
}

// 滑块改变回调
watch(
	() => mappingProps.modelValue,
	(value, oldValue) => {
		if (value === oldValue) return;
		// 如果已经报了必填错误，更改时校验下
		if (displayedRequiredError.value) validate();

		// 实现本组件的 v-model
		emit('update:modelValue', value)
		// change回调
		emit('change', value)
	}
)
</script>

<style lang="scss">
@import './index.scss';
</style>
